package com.emailsystem.emailsystem.service.impl;

import com.emailsystem.emailsystem.dao.Impl.EmailDAO;
import com.emailsystem.emailsystem.dao.Impl.UserDAO;
import com.emailsystem.emailsystem.domain.Completion;
import com.emailsystem.emailsystem.domain.Email;
import com.emailsystem.emailsystem.util.Impl.FileUtilImpl;
import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.net.SocketFactory;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import java.io.*;
import java.net.Socket;
import java.util.StringTokenizer;

@Data
@Service
public class POP3Impl {
    private Socket socket;
    private int mailNumber;
    private String account;
    @Autowired
    private EmailDAO emailDao;
    @Autowired
    private UserDAO userDao;


    public boolean sameAccount(String account) {
        if (this.account == null) {
            return false;
        }
        return this.account.equals(account);
    }

    public void init(String host, Integer port){
        try {
            if (995 == port) {
                SocketFactory socketFactory = SSLSocketFactory.getDefault();
                socket = socketFactory.createSocket(host, port);
                ((SSLSocket) socket).setEnabledProtocols(new String[]{"TLSv1.2"});
            } else {
                socket = new Socket(host, port);
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            System.out.println("成功建立连接！");
        }
    }
//    POP3Impl(String host, int port) {
//        try {
//            if (995==port) {
//                SocketFactory socketFactory = SSLSocketFactory.getDefault();
//                socket = socketFactory.createSocket(host, port);
//            }else{
//                socket = new Socket(host, port);
//            }
//        } catch (IOException e) {
//            throw new RuntimeException(e);
//        } finally {
//            System.out.println("成功建立连接！");
//        }
//    }

    public String getReadLine(BufferedReader br) {
        String line = null;
        try {
            line = br.readLine();
            System.out.println("服务器返回状态:" + line);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return line;
    }

    public String sendServer(String str, BufferedReader br, BufferedWriter bw) throws IOException {
        bw.write(str);
        bw.newLine();
        bw.flush();
        System.out.println("发送命令：" + str);
        return getReadLine(br);
    }

    public String Account(String user, BufferedReader br, BufferedWriter bw) throws IOException {
        String line = getReadLine(br);
        if (!line.startsWith("+OK")) {
//            throw new IOException("服务器连接失败！");
//            System.out.println("服务器连接失败");
        return "服务器连接失败";
        }
        line = sendServer("user " + user, br, bw);
        if (!line.startsWith("+OK")) {
//            throw new IOException("用户名错误！");
//            System.out.println("用户名错误");
            return "账号错误";
        }
        return "账号正确";
    }

    public String Pass(String password, BufferedReader br, BufferedWriter bw) throws IOException {
        String line = sendServer("pass " + password, br, bw);
        if (!line.startsWith("+OK")) {
//            throw new IOException("密码错误！");
//            System.out.println("密码错误");
            return "密码错误";
        }
        return "密码正确";
    }

    public Integer Stat(BufferedReader br, BufferedWriter bw) throws IOException {
        int mailNum = 0;
        String line = sendServer("stat", br, bw);
        StringTokenizer st = new StringTokenizer(line, " ");
        String result = st.nextToken();
        if (st.hasMoreTokens()) {
            mailNum = Integer.parseInt(st.nextToken());
        }
        if (!result.equals("+OK")) {
//            throw new IOException("查看邮箱状态错误！");
            System.out.println("未能正确查看邮箱状态");

        }

        System.out.println("共有邮件" + mailNum + "封");
        return mailNum;
    }

    public void List(BufferedReader br, BufferedWriter bw) throws IOException {
        String msg = "";
        String line = sendServer("list", br, bw);
        while (!".".equalsIgnoreCase(line)) {
            msg = msg + line + '\n';
            line = br.readLine();
        }
        System.out.println(msg);
    }

    public void ListOne(int mailNumber, BufferedReader br, BufferedWriter bw) throws IOException {
        String line = sendServer("list " + mailNumber, br, bw);
        if (!line.startsWith("+OK")) {
//            throw new IOException("list错误!");
            System.out.println("未能正确list");

        }
    }

    public Email Retr(int mailNum, BufferedReader br, BufferedWriter bw) throws IOException, InterruptedException {
        String line = sendServer("retr " + mailNum, br, bw);
        if (!line.startsWith("+OK")) {
            System.out.println("接收邮件出错!");
            return null;
        }

        String message=getMessagedetail(br);
        //获取全部
        FileWriter fileWriter = new FileWriter("./retr.txt",true);
//        //只获取错的那封
//        FileWriter fileWriter = new FileWriter("./retr.txt");
        fileWriter.append(message);
//        fileWriter.flush();
        fileWriter.close();

        try {
            Email email=FileUtilImpl.Decode_QQMail(message);
            return email;
        }catch (Exception e) {
//            throw new RuntimeException("第"+mailNum+"封邮件解析失败！");
            System.out.println("============第"+mailNum+"封邮件解析失败！============");
            return null;
        }
        //测试
//        return null;
    }

    public void Dele(int num,BufferedReader br, BufferedWriter bw) throws IOException {
        String line = sendServer("DELE "+num, br, bw);
        if (!line.startsWith("+OK")) {
            System.out.println("未能正确删除");
//            throw new IOException("未能正确删除");
        }
    }
    public void Rset(BufferedReader br, BufferedWriter bw) throws IOException {
        String line = sendServer("RSET", br, bw);
        if (!line.startsWith("+OK")) {
            System.out.println("未能正确重置");
//            throw new IOException("未能正确重置");
        }
    }
    public void Quit(BufferedReader br, BufferedWriter bw) throws IOException {
        String line = sendServer("QUIT", br, bw);
        if (!line.startsWith("+OK")) {
//            throw new IOException("未能正确退出");
        System.out.println("未能正确退出");
        }

    }

    public String getMessagedetail(BufferedReader br) throws UnsupportedEncodingException {
        StringBuilder message = new StringBuilder("");
        try {
            String line = br.readLine();
//            line=URLDecoder.decode(line, "UTF-8");
            while (!".".equalsIgnoreCase(line)) {
                message = message.append(line + "\r\n");
                line = br.readLine();
//                System.out.println(line.contains("\r\n"));
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

        return message.toString();
    }

    public String login(String user, String password) throws IOException{
        BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
        //登录
        //验证账号
        String msg1 = Account(user, br, bw);
        if (msg1.equals("账号正确")) {
            //验证密码
            String msg2 = Pass(password, br, bw);
            if (msg2.equals("密码正确")) {
                return "登陆成功";
            }else{
                return msg2;
            }
        }
        return msg1;
    }
    public Integer getCurrentNums(String user, String password) throws IOException {

        BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
        //登录
        Account(user, br, bw);
        Pass(password, br, bw);
        //状态信息
        int newNumber=Stat(br, bw);
        return newNumber;
    }
    public void receiverNewEmail(String account, String password,int begin,int length) throws IOException {
        try {
            BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
            //状态信息
            Stat(br, bw);
            Completion completion = userDao.getCompletionByAccount(account);
            for(int i=0;i<length;i++){
                System.out.printf("length================================"+length);
                Email email=Retr(begin++, br, bw);
                if(null!=email){
                    Integer existence = emailDao.selectExistenceByEmailID(email.getEmailID());
                    if (existence != null) {
//                        已存在,不要重复插入
                        continue;
                    }
                    emailDao.insertEmail(
                            email.getEmailID(), email.getSender(), email.getReceiver(), email.getSubject(),email.getContent(),email.getSendTime(),
                            email.getSenderNickname(),email.getReceiverNickname(),email.getSeen(),email.getFlagged(),email.getDeleted(),email.getAttachmentName());
//                    然后记录行为
                    String receiveEmail = completion.getReceiveEmail();
                    if (receiveEmail.length()>0)receiveEmail+=","+email.getEmailID();
                    //第一个emailid
                    else{
                        receiveEmail = email.getEmailID();
                    }
                    completion.setReceiveEmail(receiveEmail);
                }
            }
            userDao.updateCompletionOnlyReceived(completion.getReceiveEmail(),account);
        } catch (IOException | InterruptedException e) {
            throw new RuntimeException(e);
        }finally {
            socket.close();
        }
    }

    //小测试用
//public static void main(String args[]) {
//    String host="pop.qq.com";
//    POP3Impl pop3 = new POP3Impl();
//    pop3.init(host,110);
//    String user="2081510953@qq.com";
//    String password="wmzcxqbcessndajj";
//    pop3.receiverNewEmail(user, password);
//}
}

